package database

import (
	"database/sql"
	"errors"
	"gitee.com/hakwolf/dbmagic/golib/internal/models"
	"gitee.com/hakwolf/dbmagic/golib/internal/modules/configdbg"
	"gitee.com/hakwolf/dbmagic/golib/internal/routers/dhost"
	"gitee.com/hakwolf/dbmagic/golib/internal/sqldriver"
	"runtime"

	//"gitee.com/hakwolf/taibak/internal/modules/myvcl"
	"strconv"
)

//type GDatabaseType int

const (
	DSqlNone = iota
	DSqlserver
	DMysql
	DOracal
	DPostgreSQL
	DSQLite
	DInterbase
)
const (
	DSqlConnectMode = iota
	DSqlConnectlocal
	DSqlConnectRemote
)

const (
	DSqlAuthentica = iota
	DSqlAuthenticaWindow
	DSqlAuthenticaSql
)

type DBTest struct {
	Id     int
	DbType int
	Host   string
	User   string
	Psd    string
	Port   int64
	Wmode  int
	Db     string
}

func DatabaseInfoTest(dbinfo DBTest) error {
	//testdll := dylib.NewLazyDLL("qjh.dll")
	//defer testdll.Close()

	switch dbinfo.DbType {
	case DSqlserver:
		db := sqldriver.GetMssqlDbTest(dbinfo.Host, dbinfo.User, dbinfo.Psd, dbinfo.Db, dbinfo.Wmode == DSqlAuthenticaWindow, dbinfo.Port)
		err := db.Open()
		if err != nil {
			return err
		}
		_, errQ := db.Query("select @@version")
		return errQ
	case DMysql:
		db, err := GetDbEng("mysql", dbinfo.Host, dbinfo.User, dbinfo.Psd, "mysql", int(dbinfo.Port))
		if err == nil {
			if db != nil {
				defer db.Close()
			}
			_, err = db.Query("select version();")
			//return err
		}
		return err
	default:
		return errors.New("暂时不支持的数据库")

	}
	return nil

}

func GetDBname(dbtype int) string {
	switch dbtype {
	case DSqlserver:
		return "sqlserver"
	case DMysql:
		return "mysql"
	case DOracal:
		{
			return "oracle"
		}
	case DPostgreSQL:
		{
			return "PostgreSQL"
		}
	}
	return ""

}

type Cm_DbInfo struct {
	ShiliId int //任务ID
	DType   int //查询那个  0、全部数据库 /1、全部数据库,不含系统库/ 2、选定的数据库
}

type Sm_DbInfo struct {
	Dbname     string
	Tables     []string
	CreateTime string
	CompaLevel string
	FileName   string
	Bcheck     bool
}

func GetDatabaseInfo(shiLiID int, dType int) ([]Sm_DbInfo, error) {
	//testdll := dylib.NewLazyDLL("qjh.dll")
	//defer testdll.Close()

	hostModel := new(models.DHost)
	var err error
	var curHost models.DHost
	curHost, err = hostModel.Detail(shiLiID)
	if err == nil {

		//return err

		//sqlport := int(curHost.Port) //61012
		//serverIp := curHost.Host
		//curUser := curHost.User
		//curpwd := curHost.Password

		sqltype := curHost.Databasetype
		//const (
		//	DSqlNone = iota
		//	DSqlserver
		//	DMysql
		//	DOracal
		//)

		// 无参数，但返回值为int64  127.0.0.1,61012
		//Consqlquery := testdll.NewProc("consqlquery")
		querystr := ""

		switch sqltype {
		case DSqlserver:
			{
				if dType == 1 || dType == 3 {
					querystr = "Select [dbid],[name] As 数据库名称,CONVERT(varchar,[crdate],120) As 创建时间,Cast([cmptlevel] AS varchar) As 兼容级别,[filename] As 文件名 From master.dbo.sysdatabases Where 1=1"
				} else if dType == 2 {
					querystr = "Select [dbid],[name] As 数据库名称,CONVERT(varchar,[crdate],120) As 创建时间,Cast([cmptlevel] AS varchar) As 兼容级别,[filename] As 文件名 From master.dbo.sysdatabases Where 1=1 And [name] <> 'master' And [name] <> 'tempdb' And [name] <> 'model' And [name] <> 'msdb' And [name] <> 'Northwind' And [name] <> 'pubs'"
				}
			}
		case DMysql:
			{
				querystr = "SHOW DATABASES;"
			}
		}

		configdbg.Println("querystr=" + querystr)
		//s := mylcl.NewJSONObject()
		//
		//dbinfo := mylcl.NewTDBInfo()
		//dbinfo.SetPPP(int32(curHost.Port)) //61012
		//dbinfo.SetIDDD(int32(sqltype))
		//dbinfo.SetHHH(curHost.Host)
		//dbinfo.SetUUU(curHost.User)
		//dbinfo.SetPPP2(curHost.Password)

		switch sqltype {
		case DSqlserver:
			{
				//dbinfo.SetDB("master") //mysql
				return ExecQuerySqlChild(shiLiID, querystr, "master", dType)
			}
		case DMysql:
			{
				return ExecQuerySqlChild(shiLiID, querystr, "mysql", dType)
			}
		default:
			{
				//dbinfo.SetDB("")
			}
		}

		//dbinfo.SetSQL(querystr)

		//s.Consqlquery(dbinfo)

		//list := make([]Sm_DbInfo, 0)
		//ss := s.GetJSONArray("data")
		//configdbg.Println("ss.Count()=" + string(ss.Count()))
		//configdbg.Println("ss.FormatJSON()=" + ss.FormatJSON()) 换成go1.20的直接power编译 发现报错是这行造成的，客户端怎么change数据库 屏蔽会这个就不会报错了
		//configdbg.Println("ss.FormatJSON()=" + ss.FormatJSON()) go1.163屏蔽这个也正常了

		//itemC := int(ss.Count())
		//for I := 0; I < itemC; I++ {
		//	//jsobj := mylcl.AsJSONObject(ss.Items(int32(I)))
		//	//configdbg.Println(jsobj.GetString("数据库名称"))
		//	//smDbInfo := Sm_DbInfo{jsobj.GetString("数据库名称"), jsobj.GetString("创建时间"),
		//	//	jsobj.GetString("兼容级别"), jsobj.GetString("文件名"), false}
		//	list = append(list, smDbInfo)
		//}
		//configdbg.Println(list)

		//data := ret
		//configdbg.Println(data)

		//lcl.TStringList{}
		//return list, nil
	} else {
		return nil, err
	}

	return nil, err
}

func ExecQuerySqlChild(hostid int, sql, dbname string, dType int) ([]Sm_DbInfo, error) {
	hostModel := new(models.DHost)
	var err error
	var curHost models.DHost
	curHost, err = hostModel.Detail(hostid)
	Sm_DbInfos := make([]Sm_DbInfo, 0)
	if err == nil {
		sqltype := curHost.Databasetype
		//dbinfo := mylcl.NewTDBInfo()
		//dbinfo.SetPPP(int32(curHost.Port)) //61012
		//dbinfo.SetIDDD(int32(sqltype))
		//dbinfo.SetHHH(curHost.Host)
		//dbinfo.SetUUU(curHost.User)
		//dbinfo.SetPPP2(curHost.Password)
		switch sqltype {
		case DSqlserver:
			{
				//dbinfo.SetDB(dbname) //这个看要不要选或者填数据库名 在执行脚本

				if runtime.GOOS == "linux" {

				} else if runtime.GOOS == "windows" {
					///if > sql2000以上驱动
					/////非windows登录的
					db := dhost.GetMssqlDb(curHost, dbname, DSqlAuthenticaWindow) //, sql, dbname) //sql2000以上的ado的驱动=windows
					ers := db.Open()
					if ers != nil {
						configdbg.Println("sql open:", err)
						return nil, ers
					}
					defer db.Close()
					Rows, errQ := db.Query(sql)
					if errQ != nil {
						return nil, errQ
					}
					for Rows.Next() {
						var sminfo Sm_DbInfo
						var id int
						var name, createtime, cmptlevel, filename string
						Rows.Scan(&id, &name, &createtime, &cmptlevel, &filename)
						configdbg.Println(id, name, createtime, cmptlevel, filename)

						sminfo.Dbname = name
						sminfo.FileName = filename
						sminfo.CompaLevel = cmptlevel
						sminfo.CreateTime = createtime
						Sm_DbInfos = append(Sm_DbInfos, sminfo)
					}

					/////windows登录的

					////else if >= sql2005
					//intport := int(curHost.Port)
					/////非windows登录的
					//sqldriver.EXECmssqldbsqlNew(&curHost.Host, &curHost.User, &curHost.Password, &intport,sql,dbname)
					/////windows登录的

				}
			}
		case DMysql:
			{
				db, errdb := GetDbEng("mysql", curHost.Host, curHost.User, curHost.Password, "mysql", int(curHost.Port))
				if errdb == nil {
					defer db.Close()
					Rows, errQ := db.Query(sql)
					if errQ != nil {
						return nil, errQ
					}
					for Rows.Next() {
						var sminfo Sm_DbInfo
						var Database string
						Rows.Scan(&Database)
						configdbg.Println(Database)

						if dType == 2 {
							//sys：MySQL 5.7 版本后，安装完成后会多一个 sys 数据库。sys 数据库主要提供了一些视图，数据都来自于 performation_schema，主要是让开发者和使用者更方便地查看性能问题。
							if Database == "information_schema" || Database == "performance_schema" || Database == "mysql" {
								continue
							}

						}

						sminfo.Dbname = Database
						sminfo.Tables = []string{}
						RowsTb, errTb := db.Query("SHOW TABLES;")
						if errTb != nil {
							return nil, errTb
						}
						for RowsTb.Next() {
							var lvTable string
							RowsTb.Scan(&lvTable)
							configdbg.Println("表=", lvTable)
							sminfo.Tables = append(sminfo.Tables, lvTable)
						}
						//sminfo.FileName = filename
						//sminfo.CompaLevel = cmptlevel
						//sminfo.CreateTime = createtime
						Sm_DbInfos = append(Sm_DbInfos, sminfo)
					}

				}

				//if s.Db.Engine == "postgres" && err != nil {
				//	pgError, ok := err.(*pq.Error)
				//	if ok && pgError.Code == "3D000" {
				//		err = errors.New("数据库不存在")
				//	}
				//	return err
				//}
				//
				//if s.Db.Engine == "mysql" && err != nil {
				//	mysqlError, ok := err.(*mysql.MySQLError)
				//	if ok && mysqlError.Number == 1049 {
				//		err = errors.New("数据库不存在")
				//	}
				//	return err
				//}
				//dbinfo.SetDB("")
			}
		default:
			{
				//dbinfo.SetDB("") //这个看要不要选或者填数据库名 在执行脚本
			}
		}

		//dbinfo.SetSQL(sql)
		//mylcl.ConsqlExeSql(dbinfo)
	}
	return Sm_DbInfos, err
}

func GetDbEng(DbType, DbHost, DbUsername, DbPassword, DbName string, DbPort int) (db *sql.DB, err error) {
	//var s setting.Setting
	//s.Db.Engine = DbType
	//s.Db.Host = DbHost
	//s.Db.Port = DbPort
	//s.Db.User = DbUsername
	//s.Db.Password = DbPassword
	//s.Db.Database = DbName
	//s.Db.Charset = "utf8"
	//db, err = models.CreateTmpDb(&s)
	switch DbType {
	case "mysql":
		db, err = sql.Open("mysql", DbUsername+":"+DbPassword+"@tcp("+DbHost+":"+strconv.Itoa(DbPort)+")/"+DbName+"?charset=utf8")
	default:

	}
	return
	//defer db.Close()
	//err = db.Ping()
}

func GetDatabaseInfotest(ShiLiID int) {
	//s := lcl.NewStringList()
	//s.Add()
}

//func CheckBox_PaintTo(obj uintptr, DC HDC, X int32, Y int32)  {
//	checkBox_PaintTo.Call(obj, uintptr(DC) , uintptr(X) , uintptr(Y) )
//}

//Select [dbid],[name] As 数据库名称,CONVERT(varchar,[crdate],121) As 创建时间,Cast([cmptlevel] AS varchar) As 兼容级别,[filename] As 文件名 From master.dbo.sysdatabases Where 1=1

//Select [dbid],[name] As 数据库名称,CONVERT(varchar,[crdate],121) As 创建时间,Cast([cmptlevel] AS varchar) As 兼容级别,[filename] As 文件名 From master.dbo.sysdatabases Where 1=1 And [name] <> 'master' And [name] <> 'tempdb' And [name] <> 'model' And [name] <> 'msdb' And [name] <> 'Northwind' And [name] <> 'pubs'
